import fs from 'fs';
import path from 'path';
import { Application } from 'kilom/lib/Application';
import { getFormat } from './util';
import { loadData } from '../config/Xlsx';
import { MsgCoder } from '../config/Msg';

let app: Application;
let format: string;
let msgPath: string;
let msgCfgPath: string;
let msgStructPath: string;
let xlsxPath: string;
let xlsxDataPath: string;

/**
 * 初始化热更模块
 * @param _app
 */
export function initHotfix(_app: Application) {
    app = _app;
    format = getFormat(app)
    msgPath = path.resolve(app.base, "config/Msg" + format);
    msgCfgPath = path.resolve(app.base, "config/MsgCfg" + format);
    msgStructPath = path.resolve(app.base, "config/MsgStruct" + format);
    xlsxPath = path.resolve(app.base, "config/Xlsx" + format);
    xlsxDataPath = path.resolve(app.base, "../config/data.bin");

    if (app.miscCfg.autoReloadHandler) {
        let msgTimer: NodeJS.Timeout;
        fs.watch(msgPath, () => {
            msgTimer && clearTimeout(msgTimer);
            msgTimer = setTimeout(() => {
                msgTimer = null;
                hotMsg();
            }, 1000);
        });

        let xlsxTimer: NodeJS.Timeout;
        [xlsxPath, xlsxDataPath].forEach(path => {
            fs.watch(path, () => {
                xlsxTimer && clearTimeout(xlsxTimer);
                xlsxTimer = setTimeout(() => {
                    xlsxTimer = null;
                    hotXlsx();
                }, 1000);
            });
        })
    }
}

/**
 * 热重载协议
 */
export function hotMsg() {

    let modMsg = require.cache[msgPath];
    let modMsgStruct = require.cache[msgStructPath];

    try {
        if (app.isTs) {
            //重载下ts类型
            delete require.cache[msgPath];
            require(msgPath);
            require.cache[msgPath] = modMsg;
        }
        delete require.cache[msgCfgPath];
        delete require.cache[msgStructPath];
        if (!app.reloadMsgCfg(msgCfgPath)) throw new Error("重载消息路由配置失败");
        let msgStruct = require(msgStructPath).default;
        MsgCoder.loadAll(msgStruct);
        app.logger.info("已热重载协议");
    } catch (err) {
        require.cache[msgPath] = modMsg;
        require.cache[msgStructPath] = modMsgStruct;
        app.logger.error("热重载协议失败: " + (err as Error).message);
    }

}

/**
 * 热重载表
 */
export function hotXlsx() {

    let modXlsx = require.cache[xlsxPath];
    try {
        if (app.isTs) {
            //重载下ts类型
            delete require.cache[xlsxPath];
            require(xlsxPath);
            require.cache[xlsxPath] = modXlsx;
        }
        loadData(fs.readFileSync(xlsxDataPath));
        app.logger.info("已热重载表");
    } catch (err) {
        require.cache[xlsxPath] = modXlsx;
        app.logger.error("热重载表失败: " + (err as Error).message);
    }

}